/**
 * 20220304:[require] to [import]...jordia
 * 20220704:1.add different logic for perspective and orthographic camera
 *          2.change degree limitAngle to radian; 
 */
import {Ray,Plane,Vector3} from 'three';
import DragLimit from "./drag-limit";
import Geometry from "../../general/geometry-utils";


/**
 * 沿向量拖动
 * @param values {object}
 * limitAngle:0.1 拖动角度小于此值时将锁定不能拖动，避免小角度时突然拖到极远
 * 继承的其它...
 */
export default class DragPlaneLimit extends DragLimit{
    constructor(values){
        super(values);
    }

    /**
     * 获取约束类型
     * @returns {string}
     */
    get type(){
        return 'dragPlaneLimit';
    }

    /**
     * 获取平面法线
     * @returns {null|Vector3}
     */
    get normal(){
        return this._normal;
    }

    /**
     * 设置平面法线
     * @param vector
     */
    set normal(vector){
        this._normal.copy(vector);
    }

    /**
     * 获取锁定角度
     * @returns {number}
     */
    get limitAngle(){
        return this._limitAngle;
    }

    /**
     * 设置锁定角度
     * @param rad
     */
    set limitAngle(rad){
        this._limitAngle=rad;
    }

    modifyMove(object,v,callback,camera) {
        /**
         * 20220704
         */
        const origin=this._cameraPosition;
        object.getWorldPosition(this._tempPosition);
        this._tempDir.copy(this._normal);
        this._tempPlane.setFromNormalAndCoplanarPoint(this._tempDir,this._tempPosition);
        this._getRayComponents(camera,v,origin,this._tempDirection);

        let tempAngle = Geometry.lineAngleToPlane(origin, v, this._tempDir, false);
        if (tempAngle < this._limitAngle) {
            return;
        }
        this._tempRay.set(origin, this._tempDirection);
        let iPoint =new Vector3();
        this._tempRay.intersectPlane(this._tempPlane,iPoint);
        if(!iPoint)return;
        this._transformVector(object,iPoint);
        object.position.copy(iPoint);
        callback(object,iPoint);
    }
    dispose(){
        super.dispose();
        this._limitAngle=null;
        this._normal=null;
        this._tempPosition=null;
        this._cameraPosition=null;
        this._tempDirection=null;
        this._tempDir=null;
        this._tempRay=null;
        this._tempPlane=null;
    }

    _initVariable() {
        super._initVariable();
        this._limitAngle=this._values.limitAngle||(10*Math.PI/180);

        this._normal=new Vector3(0,1,0);
        this._tempPosition=new Vector3();
        this._cameraPosition=new Vector3();
        this._tempDirection=new Vector3();
        this._tempDir=new Vector3();
        this._tempRay=new Ray();
        this._tempPlane=new Plane();
    }
}